/*
* @File Name ps_timer.c
* @File Path M:\MAS2\PRM_Robotic_Arm\PRMCcode\coding\peripheral\timer_usr\ps_timer.c
* @Author: Ruige_Lee
* @Date:   2019-09-01 17:27:04
* @Last Modified by:   Ruige_Lee
* @Last Modified time: 2019-09-24 19:14:51
* @Email: 295054118@whut.edu.cn
* @page: https://whutddk.github.io/
*/
/*
* @File Name ps_timer.c
* @File Path M:\MAS2\PRM_Robotic_Arm\PRMCcode\coding\peripheral\timer_usr\ps_timer.c
* @Author: Ruige_Lee
* @Date:   2019-04-17 16:45:03
* @Last Modified by:   Ruige_Lee
* @Last Modified time: 2019-04-17 16:51:46
* @Email: 295054118@whut.edu.cn"
*/




#include <stdint.h>
#include <stdlib.h>

#include "peripheral/ps_perip.h"


#include "xscutimer.h"
#include "xtime_l.h"

#include "xparameters.h"
#include "xscutimer.h"
#include "xscugic.h"
#include "xil_exception.h"


#define TIMER_LOAD_VALUE                           0x28B0B	// 500us

//static parameter declare
static int32_t s_timer_cnt = 0;


static void timer_user_handler(void *CallBackRef);




XScuTimer TimerInstance;	//Cortex A9 Scu Private Timer Instance
XScuGic IntcInstance;		//Interrupt Controller Instance

int32_t Xscu_timer_init()
{
	XScuTimer_Config *ConfigPtr;
	ConfigPtr = XScuTimer_LookupConfig(XPAR_XSCUTIMER_0_DEVICE_ID);
	
	if ( XST_SUCCESS != XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr,ConfigPtr->BaseAddr) ) 
	{
		return XST_FAILURE;
	}

	if ( XST_SUCCESS != XScuTimer_SelfTest(&TimerInstance) ) 
	{
		return XST_FAILURE;
	}

		XScuGic_Config *IntcConfig;
		IntcConfig = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
		if ( NULL == IntcConfig ) 
		{
			return XST_FAILURE;
		}
		if ( XST_SUCCESS != XScuGic_CfgInitialize(&IntcInstance, IntcConfig,IntcConfig->CpuBaseAddress) ) 
		{
			return XST_FAILURE;
		}


		Xil_ExceptionInit();
		Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&IntcInstance);

		if ( XST_SUCCESS != XScuGic_Connect(&IntcInstance, XPAR_SCUTIMER_INTR,(Xil_ExceptionHandler)timer_user_handler,(void *)(&TimerInstance)) ) 
		{
			return XST_FAILURE;
		}

		XScuGic_Enable(&IntcInstance, XPAR_SCUTIMER_INTR);
		XScuTimer_EnableInterrupt(&TimerInstance);
		Xil_ExceptionEnable();

	XScuTimer_EnableAutoReload(&TimerInstance);
	XScuTimer_LoadTimer(&TimerInstance, TIMER_LOAD_VALUE);
	XScuTimer_Start(&TimerInstance);


	srand(XScuTimer_GetCounterValue(&TimerInstance));
	return XST_SUCCESS;
}

extern void timer_usr_500us();
extern void timer_usr_10ms();
extern void timer_usr_100ms();
extern void timer_usr_500ms();
extern void timer_usr_1s();
extern void timer_usr_2s();



uint8_t flag_500us = 0;
uint8_t flag_10ms = 0;
uint8_t flag_100ms = 0;
uint8_t flag_500ms = 0;
uint8_t flag_1s = 0;
uint8_t flag_2s = 1;

static void timer_user_handler(void *CallBackRef)
{
	s_timer_cnt++;

	// 500us
	timer_usr_500us();
	flag_500us = 1;
	
	if ( 10	== ( s_timer_cnt % 20  ) )
	{
		// 10ms 错相5ms
		timer_usr_10ms();
		flag_10ms = 1;	
	}	

	if ( 0 == ( s_timer_cnt % 200 ) )
	{
		// 100ms
		timer_usr_100ms();
		flag_100ms = 1;
	}

	if ( 0 == ( s_timer_cnt % 1000 ) )
	{
		// 500ms
		timer_usr_500ms();
		flag_500ms = 1;
	}

	if ( 0 == ( s_timer_cnt % 2000 ) )
	{

		// 1000ms
		timer_usr_1s();
		flag_1s = 1;
	}

	if ( 0 == ( s_timer_cnt % 2000 ) )
	{

		s_timer_cnt = 0;
		// 2000ms
		timer_usr_2s();
		flag_2s = 1;
	}


	//clear interrupt flag
	{	
		XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;

		if (XScuTimer_IsExpired(TimerInstancePtr))
		{
			XScuTimer_ClearInterruptStatus(TimerInstancePtr);
		}
	}

}




